// 游戏配置
var gameConfig = {
    width: 500,
    height: 500,
    rows: 3, //行数
    cols: 3, //列数
    imgUrl: "./lol.png",//图片路径，注意是相对页面的路径
    dom: document.querySelector("#game"), //游戏的dom对象
    isOver:false, //判断游戏是否结束
}
// 每一个小块的宽高
gameConfig.pieceWidth = gameConfig.width / gameConfig.cols;
gameConfig.pieceHeight = gameConfig.height / gameConfig.rows;
// 小块的数量
gameConfig.pieceNumberS = gameConfig.cols * gameConfig.rows;

var blocks = [];//包含小方块信息的数组
// 构造函数,  isVisible表示小方块是否可见
function Block(left, top, isVisible) {
    // left和top是小块当前的横纵坐标啊
    this.left = left;
    this.top = top;
    // currentLeft和currentTop是小块正确位置的横纵坐标
    // 初始时正确位置的横纵坐标就为当前的横纵坐标
    this.currentLeft = this.left;
    this.currentTop = this.top;
    // 创建小方块的dom元素
    this.dom = document.createElement("div");
    this.dom.style.width = gameConfig.pieceWidth + "px";
    this.dom.style.height = gameConfig.pieceHeight + "px";
    // 设置小方块背景图和背景图的位置
    this.dom.style.background = `url(${gameConfig.imgUrl}) -${this.currentLeft}px -${this.currentTop}px`;
    this.dom.style.position = "absolute";
    this.dom.style.border = "1px solid #fff";
    this.dom.style.boxSizing = "border-box";
    this.dom.style.cursor = "pointer";
    gameConfig.dom.appendChild(this.dom);
    if (isVisible == false) {
        this.dom.style.display = "none";
    }
    this.show = function () {
        this.dom.style.left = this.left + "px";
        this.dom.style.top = this.top + "px";
    }

    this.show();
}

/**
 * 初始化游戏
 */
function init() {
    initGameDom();
    initBlocksArray();
    shuffle();
    regEvent();
    // 1.初始化游戏的容器
    function initGameDom() {
        gameConfig.dom.style.width = gameConfig.width + "px";
        gameConfig.dom.style.height = gameConfig.height + "px";
        gameConfig.dom.style.border = "1px solid #000";
        // 由于内部小的div块要移动，都需要设置成为绝对定位，所以这里需要给外层容器设置相对定位
        gameConfig.dom.style.position = "relative";
    }
    // 2.初始化小方块
    // 2.1 准备好一个数组，数组的每一项是一个对象，记录了每一个小方块的信息
    function initBlocksArray() {
        for (var i = 0; i < gameConfig.rows; i++) {
            for (var j = 0; j < gameConfig.cols; j++) {
                var isVisible = true;
                if (i === (gameConfig.rows - 1) && j === (gameConfig.cols - 1)) {
                    isVisible = false;
                }
                blocks.push(new Block(j * gameConfig.pieceWidth, i * gameConfig.pieceHeight, isVisible))
            }
        }
    }

    // 交换两个函数的left和top
    function exchange(b1, b2) {
        var middle1 = b1.left;
        var middle2 = b1.top;
        b1.left = b2.left;
        b1.top = b2.top;
        b2.left = middle1;
        b2.top = middle2;
        b1.show();
        b2.show();
    }

    // 3.打乱数组blocks
    function shuffle() {
        // 随机从数组中取两项，然后交换left和top值
        for (var i = 0; i < blocks.length - 1; i++) {
            // 随机产生一个下标，交换i下标与这个随机产生的下标
            var index = parseInt(Math.random() * blocks.length - 1);
            exchange(blocks[i], blocks[index]);
        }
    }


    // 4.注册点击事件
    function regEvent() {
        var inVisibleBlock = blocks.find((b) => {
            // find：从数组中查找满足条件的元素
            return b.dom.style.display === "none";

        })
        blocks.forEach((b) => {
            b.dom.onclick = function () {
                if(gameConfig.isOver){
                    return;
                }
                // 判断是否可以交换,只有相邻的才可以进行交换
                if ( (b.left === inVisibleBlock.left && (Math.abs(b.top - inVisibleBlock.top) === gameConfig.pieceHeight)) ||
                    (b.top === inVisibleBlock.top && (Math.abs(b.left - inVisibleBlock.left) === gameConfig.pieceWidth))) {
                    // 交换当前方块与看不见的方块的坐标位置
                    exchange(b, inVisibleBlock);
                }
                // 游戏结束判定
                isWin();
            }
        })
    }
    // 判断游戏是否结束
    function isWin(){
        // 查找不在正确位置的方块
        var wrongs = blocks.filter((b)=>{
            if(b.left!==b.currentLeft||b.top!==b.currentTop){
                return true;
            }
        })
        if(wrongs.length===0){
            // 此时游戏完成，去掉所有的边框，全部显示出来
            blocks.forEach((b)=>{
                b.dom.style.border="none"
                b.dom.style.display="block";
            })
            gameConfig.isOver=true;
        }
       
    }
}
init();



